package mall

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"golang.org/x/crypto/bcrypt"
	"log"
	"mall-go/common"
	"mall-go/model"
	"mall-go/response"
	"mall-go/util"
	"net/http"
)

func Login(c *gin.Context) {
	DB := common.GetDB()
	//获取参数
	var requestUser = model.MallUser{}
	c.Bind(&requestUser)
	//获取用户名密码
	mobliePhone := requestUser.LoginName
	passwordMd5 := requestUser.PasswordMd5
	//判断手机号是否为11位
	if !util.IsMobile(mobliePhone) {
		response.Failure(c, nil, "请输入正确的手机号！")
		return
	}
	//根据手机号和密码查询用户
	var mallUser model.MallUser
	DB.Where("login_name = ?", mobliePhone).First(&mallUser)
	fmt.Printf("查询到用户：%v", mallUser)
	//判断密码是否正确
	if err := bcrypt.CompareHashAndPassword([]byte(mallUser.PasswordMd5), []byte(passwordMd5)); err != nil {
		response.Failure(c, nil, "密码错误！")
		return
	}
	//用户被锁定
	if mallUser.LockedFlag == 1 {
		response.Failure(c, nil, "用户已被禁止登录！")
		return
	}
	//发放token
	token, err := common.ReleaseMallToken(mallUser)
	if err != nil {
		response.Failure(c, nil, "token发放失败！")
		return
	}
	//todo 这部分可以有个token名单，先略过
	//登录成功，封装信息
	log.Println("登录成功！")
	response.Success(c, gin.H{"token": token}, "登录成功！")
}

func Register(c *gin.Context) {
	db := common.GetDB()
	//获取参数
	hashMap := make(map[string]string)
	c.Bind(&hashMap)
	//这里因为登录注册password不一样，所以用map封装
	name := hashMap["loginName"]
	password := hashMap["password"]
	//数据验证
	//判断手机号是否为11位
	if !util.IsMobile(name) {
		response.Failure(c, nil, "请输入正确的手机号！")
		return
	}
	//判断手机号是否存在
	if isNameExist(db, name) {
		response.Response(c, http.StatusUnprocessableEntity, 422, nil, "手机号已存在")
		return
	}
	//创建用户
	//给密码加密
	hashPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		response.Response(c, http.StatusInternalServerError, 500, nil, "加密错误")
		return
	}
	newUser := model.MallUser{
		NickName:      name,
		LoginName:     name,
		PasswordMd5:   string(hashPassword),
		IntroduceSign: "请自定义简介",
		IsDeleted:     0,
		LockedFlag:    0,
	}
	log.Println(len(string(hashPassword)))
	//注册
	if err := db.Create(&newUser).Error; err != nil {
		response.Failure(c, nil, "注册失败！")
		return
	}
	//返回结果
	response.Success(c, nil, "注册成功！")
}

func isNameExist(db *gorm.DB, name string) bool {
	//这里必须新建一个，不然找不到地址
	mallUser := new(model.MallUser)
	db.Where("login_name = ?", name).First(&mallUser)
	if mallUser.UserID != 0 {
		return true
	}
	return false
}
func Logout(c *gin.Context) {
	//todo 这里是用数据库记录了token的，删除数据库记录token，即退出登录
	//暂时不处理
	response.Success(c, nil, "退出登录")
}

func GetUserDetail(c *gin.Context) {
	// 已用中间件将user信息放到上下文中  这里直接取出来用
	user, exists := c.Get("mallUser")
	if !exists {
		//基本上不会跨过中间件，这里就直接做个记录
		log.Println("非法操作，跨过中间件")
	}
	response.Success(c, gin.H{"user": user}, "获取成功！")
}

// UpdateInfo 修改用户信息
func UpdateInfo(c *gin.Context) {
	db := common.GetDB()
	//获取用户信息
	user, _ := c.Get("mallUser")
	userId := user.(model.MallUser).UserID
	var requestUser = model.MallUser{}
	c.Bind(&requestUser)
	//根据userId查询用户信息
	var oldUser model.MallUser
	db.Where("user_id = ? and is_deleted = 0", userId).First(&oldUser)
	if oldUser.UserID == 0 {
		response.Failure(c, nil, "数据不存在")
		return
	}
	oldUser.NickName = requestUser.NickName
	//若密码为空字符，则表明用户不打算修改密码，使用原密码保存
	if requestUser.PasswordMd5 != "" {
		hashPassword, err := bcrypt.GenerateFromPassword([]byte(requestUser.PasswordMd5), bcrypt.DefaultCost)
		if err != nil {
			response.Failure(c, nil, "密码加密失败")
			return
		}
		oldUser.PasswordMd5 = string(hashPassword)
	}
	oldUser.IntroduceSign = requestUser.IntroduceSign
	if err := db.Debug().Model(&oldUser).Update(oldUser).Error; err != nil {
		response.Failure(c, nil, "更新失败")
		return
	}
	response.Success(c, nil, "更新成功")
}
